home *** CD-ROM | disk | FTP | other *** search
- ## -*-Tcl-*- (nowrap)
- # ###################################################################
- # AlphaTcl - core Tcl engine
- #
- # FILE: "dialogsNew.tcl"
- # created: 12/1/96 {5:36:49 pm}
- # last update: 12/19/2000 {13:23:32 PM}
- # Author: Vince Darley
- # E-mail: <vince@santafe.edu>
- # mail: 317 Paseo de Peralta, Santa Fe, NM 87501
- # www: <http://www.santafe.edu/~vince/>
- #
- # Copyright (c) 1997-2000 Vince Darley,
- # Distributed under Tcl style free license.
- # ###################################################################
- ##
-
- namespace eval dialog {}
-
- ensureset dialog::_not_global_flag ""
-
- ##
- # -------------------------------------------------------------------------
- #
- # "dialog::make" --
- #
- # General purpose single/multi page dialog creator. Optional flags
- # at start of arguments list include:
- #
- # -title "Dialog title"
- # -defaultpage "Page name"
- # -ok "name of ok button"
- # -cancel "name of cancel button"
- # -addbuttons [list name1 help1 script1 name2 ...]
- #
- # Each of the remaining arguments is a list, starting with the name
- # of the page represented by that list, and followed by sublists for
- # each dialog item. Currently each such sublist is a triplet of
- # the form 'type name value'. An optional 4th item in the sublist
- # is the help text for that item. So,
- #
- # dialog::make -ok "Accept" -title hello -defaultpage Second \
- # {First {var Hey 1} {flag blah 0} {Folder hey ""}} {Second {var Hey 2}}
- #
- # Will create a dialog with two pages, named 'First' and 'Second'.
- # The first page contains 3 dialog items: a variable, a flag and a
- # folder item. These are 'named' Hey, blah and hey respectively,
- # and have current values 1, 0, and "" respectively. The second
- # page contains a single variable to be edited.
- #
- # This procedure returns a list of the final edited values of the
- # dialog items (just a flat list), or returns an error if the
- # dialog was cancelled.
- #
- # Unlike most of Alpha's dialog procedures, this one doesn't
- # actually modify any variable values in place. It is simply
- # a nice wrapper around the rather cumbersome core 'dialog' command,
- # which solves all the hassle of funny dialog item types
- # (particularly folders, paths, files, popup menus etc...).
- # It is up to the caller to take the returned values and store
- # the changes as appropriate.
- #
- # THIS PROC IS NOT YET REENTRANT, therefore do not use button-scripts
- # which might call this procedure to generate new recursive dialogs.
- # -------------------------------------------------------------------------
- ##
- proc dialog::make {args} {
- dialog::resetModified
- global dialog::_tmp dialog::_not_global_flag
- if {[info exists dialog::_tmp]} {
- # This shouldn't exist. The dialog must have failed last time.
- # During beta releases, we will ask the user to submit a bug
- # report.
- alertnote "The 'dialog::make' command failed with an internal error\
- last time you used it. Please try to isolate the circumstances of\
- the bug and then submit a bug report to the Alpha-D\
- mailing list"
- }
- set opts(-ok) OK
- set opts(-cancel) Cancel
- getOpts {-title -defaultpage -ok -cancel -addbuttons}
- set dialog::_not_global_flag dialog::_tmp
- # If we were given an empty dialog, return an empty result
- if {[llength $args] == 0} {return ""}
- # We need to loop to cope with the user pressing 'set...' buttons
- # which modify the dialog without exiting. Alpha8/Tk can cope with
- # set... buttons in place, so we could then remove the loop.
- while {1} {
- set x 10
- set ymax 0
- set dialog {}
- set items {}
- if {[llength $args] == 1} {
- set multipage 0
- } else {
- set multipage 1
- }
- foreach page $args {
- set pageName [lindex $page 0]
- lappend names $pageName
- if {$multipage} {
- lappend dialog -n $pageName
- }
- set y 50
- eval lappend dialog [eval [list dialog::makeFromItems $x y items] $page]
- if {$y > $ymax} {set ymax $y}
- }
- incr ymax 10
- set y $ymax
- if {![info exists opts(-defaultpage)]} {
- set opts(-defaultpage) [lindex $names 0]
- }
- if {![info exists opts(-title)]} { set opts(-title) "" }
-
- set button_help {}
- if {[info exists opts(-addbuttons)]} {
- set numbuttons 0
- set button_press {}
- set b_args {}
- set x 10
- newforeach {button bh bproc} [concat \
- [list $opts(-ok) "Click here to save the current settings." "" \
- $opts(-cancel) "Click here to discard any changes you've made to the settings." ""] \
- $opts(-addbuttons)] {
- lappend b_args $button "" y
- lappend button_help $bh
- lappend button_press $bproc
- incr numbuttons
- }
- set buttons [eval dialog::button $b_args]
- } else {
- set buttons [dialog::okcancel 10 y 0 $opts(-ok) $opts(-cancel)]
- set numbuttons 2
- lappend button_help \
- "Click here to save the current settings." \
- "Click here to discard any changes you've made to the settings."
- }
-
- set dialog [concat $buttons $dialog]
- set help {}
- if {$multipage} {
- lappend help "Use this popup menu, or the cursor keys to select a \
- different page of preferences."
- set mnames [concat [list $opts(-defaultpage)] $names]
- set dialog [concat [list -m $mnames 100 20 300 40] $dialog]
- } else {
- set dialog [concat [list -t [lindex $names 0] 100 20 300 40] $dialog]
- }
- eval lappend help $button_help
- foreach it $items {
- lappend help [lindex $it 3]
- }
- if {[info tclversion] >= 8.0} {
- # Alpha 7.x doesn't support the '-help' flag.
- set dialog [concat $dialog [list -help $help]]
- }
- if {[info tclversion] < 8.0} {
- if {[catch {eval [list dialog -w 400 -h $y] $dialog} res]} {
- # bug in internal 'dialog' command
- unset dialog::_tmp
- set dialog::_not_global_flag ""
- dialog::resetModified
- alertnote "Sorry, you encountered a bug in Alpha 7's 'dialog' command, \
- which cannot handle very complex dialogs. If you are trying to edit\
- many items at once, try to edit them just one at a time."
- error "Internal bug in 'dialog'."
- }
- } else {
- set res [eval [list dialog -w 400 -h $y -T $opts(-title)] $dialog]
- }
- if {!$multipage} {
- # Pretend there is a 'page' result.
- set res [concat [list [lindex $names 0]] $res]
- }
- if {[lindex $res 2]} {
- # Cancel
- set retCode 1 ; set retVal "Cancelled!"
- } else {
- if {[lindex $res 1]} {
- # Ok
- set retCode 0
- }
- set retVal {}
- # Get all new values, possibly checking for 'set…' button presses
- set count 3
- if {$numbuttons > 2} {
- while {$count <= $numbuttons} {
- if {[lindex $res $count]} {
- set pressScript [lindex $button_press [expr {$count -1}]]
- catch {eval $pressScript}
- }
- incr count
- }
- }
-
- foreach ii $items {
- newforeach {type page name} $ii {break}
- switch -- $type {
- Folder - Path {
- if {[lindex $res $count] == 1} {
- if {![catch {get_directory -p "New [lrange $ii 1 end]"} newval]} {
- dialog::modified "$page,$name" $newval Folder
- set dialog::_tmp($page,$name) [dialog::getFlag "$page,$name"]
- }
- }
- }
- file {
- if {[lindex $res $count] == 1} {
- set oldval [dialog::getFlag "$page,$name"]
- if {![catch {getfile [quote::Prettify "New [lrange $ii 1 end]"] $oldval} newval] \
- && $oldval != $newval} {
- dialog::modified "$page,$name" $newval file
- set dialog::_tmp($page,$name) [dialog::getFlag "$page,$name"]
- }
- }
- }
- default {
- dialog::modified "$page,$name" [lindex $res $count]
- set dialog::_tmp($page,$name) [dialog::getFlag "$page,$name"]
- }
- }
- incr count
- lappend retVal [dialog::getFlag "$page,$name"]
- }
- }
- # remember the current page
- set opts(-defaultpage) [lindex $res 0]
- if {[info exists retCode]} {break}
- }
- unset dialog::_tmp
- set dialog::_not_global_flag ""
- dialog::resetModified
- return -code $retCode $retVal
- }
-
- proc dialog::makeFromItems {x yy items page args} {
- global dialog::_tmp
- upvar $yy y
- upvar $items item
- set res {}
- foreach itemset $args {
- newforeach {type name val help} $itemset {break}
- if {![info exists dialog::_tmp($page,$name)]} {
- set dialog::_tmp($page,$name) $val
- } else {
- set val [set dialog::_tmp($page,$name)]
- }
- eval lappend res [dialog::makeItem $type $x y $page $name $val $help]
- lappend item [list $type $page $name $help]
- }
- set res
- }
-
- # In need of some work filling in other types
- proc dialog::makeItem {type x yy page name val {help ""}} {
- set res {}
- upvar $yy y
- if {[llength $type] > 1} {
- switch -- [lindex $type 0] {
- "global" {
- set v [lindex $type 1]
- global flag::list
- if {[info exists flag::list($v)]} {
- set litems [flag::options $v]
- if {[regexp "index" [lindex [set flag::list($v)] 0]]} {
- # set item to index, making sure bad values don't error
- if {[catch {lindex $litems $val} val]} { set val [lindex $litems 0] }
- }
- eval lappend res [dialog::text $name $x y 30]
- eval lappend res [dialog::menu $x y $litems $val]
- } elseif {[regexp "Colou?r$" $v]} {
- global alpha::colors
- eval lappend res [dialog::text $name $x y 30]
- eval lappend res [dialog::menu $x y ${alpha::colors} $val]
- } elseif {[regexp "Mode$" $v]} {
- if {$val == ""} { set val "<none>" }
- eval lappend res [dialog::text $name $x y 30]
- eval lappend res [dialog::menu $x y [concat "<none>" [mode::listAll]] $val]
- } else {
- eval lappend res [dialog::textedit $name $val $x y 30]
- }
- }
- "menu" {
- set items [lindex $type 1]
- eval lappend res [dialog::text $name $x y 20] \
- [dialog::menu 120 y $items $val]
- }
- default {
- error "Unsupported $type"
- }
- }
- } else {
- switch -- $type {
- "flag" {
- eval lappend res [dialog::checkbox $name $val $x y]
- }
- "Folder" {
- eval lappend res [dialog::text $name $x y 20]
- set vv [dialog::specialView::file $val]
- lappend res "-t" $vv $x $y [expr {$x + 250}] [expr {$y + 18}]
- eval lappend res [dialog::buttonSet [expr {$x + 250}] $y Folder "$page,$name"]
- incr y 18
- }
- "file" {
- eval lappend res [dialog::text $name $x y 20]
- set vv [dialog::specialView::file $val]
- lappend res "-t" $vv $x $y [expr {$x + 250}] [expr {$y + 18}]
- eval lappend res [dialog::buttonSet [expr {$x + 250}] $y file "$page,$name"]
- incr y 18
- }
- "password" {
- eval lappend res [dialog::text $name $x y 20]
- lappend res "-e" $val $x $y [expr {$x + 100}] [expr {$y+2}]
- incr y 18
- }
- default {
- eval lappend res [dialog::textedit $name $val $x y 30]
- }
- }
- }
- set res
- }
-
-
-